/*	
*	File: arp-packet.h
*	Date: 2011/11/25
*	User: Ronmaru
*	Desctiption: ARP packet class
*/

#ifndef _ARP_PACKET_H_
#define _ARP_PACKET_H_

#include "pcraft-tool.h"

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>
#include <istream>
#include <iostream>
#include <ostream>

#ifdef WIN32
#include <pcap/pcap.h>
#endif

using boost::asio::deadline_timer;
namespace posix_time = boost::posix_time;

class ARPpacket
{
public:
  ARPpacket(ETHERNETheader ethernet_header, ARPheader arp_header, int interface_number)
    : ethernet_header_(ethernet_header), arp_header_(arp_header), interface_number_(interface_number)
  {

    if (pcap_findalldevs(&devlist_, errbuf_) == -1) { 
      std::cout << "Error finding devices: " << errbuf_ << std::endl;
    } else {
      std::cout << "Found devices: " << std::endl;
      int i = 0;
      for (curdev_ = devlist_; curdev_; curdev_ = curdev_->next) { 
        ++i;
        std::cout << i << ")" << curdev_->name << std::endl;
        if (interface_number_ == i)
          selected_device_ = curdev_;
      }

      if ((fp_= pcap_open_live(selected_device_->name,            // name of the device
        100,                                                    // portion of the packet to capture (only the first 100 bytes)
        0,                                                      // promiscuous mode
        5000,                                                   // read timeout
        errbuf_                                                 // error buffer
        )) == NULL)
      {
        std::cout << "Error open the adapter " << devlist_->name << std::endl;
        return;
      } else {
        std::cout << "Socket has opened successfully!" << std::endl;
      }
    }
  }

  void send()
  {
    std::stringstream request_buffer;
    std::string str_buf;

    request_buffer << ethernet_header_ << arp_header_;
    request_buffer >> str_buf;

    if (pcap_sendpacket(fp_, reinterpret_cast<const u_char*>(str_buf.c_str()), str_buf.length()) != 0)
    {
      std::cout << "Error sending the packet: " << pcap_geterr(fp_) << std::endl;
      return;
    }

  }

  pcap_t *fp_;
  char errbuf_[PCAP_ERRBUF_SIZE];
  int interface_number_;
  pcap_if_t *devlist_;
  pcap_if_t *curdev_;
  pcap_if_t *selected_device_;

  ETHERNETheader ethernet_header_;
  ARPheader arp_header_;
};


#endif //_ARP_PACKET_H_